﻿using System;
using NazTek.Utility;

namespace NazTek.Utility.Extensions.Misc
{
    /// <summary>
    /// Extends <see cref="Exception"/>
    /// </summary>
    public static class ExceptionExtension
    {
        /// <summary>
        /// Gets the inner most exception message
        /// </summary>
        /// <param name="ex">The exception to extract inner most exception from</param>
        /// <returns>Inner most exception</returns>
        public static Exception GetBaseException(this Exception ex)
        {
            return ex.GetBaseException();
        }
        /// <summary>
        /// Gets all exception messages from the top to the inner most, concatenated by space
        /// </summary>
        /// <param name="ex">The exception to extract messages from</param>
        /// <returns>Concatenated messages</returns>
        public static string GetConcatenatedExceptionMessage(this Exception ex)
        {
            return ex.InnerException == null
                ? ex.Message
                : String.Format("{0}/n", ex.InnerException.GetConcatenatedExceptionMessage());
        }
        /// <summary>
        /// Formats exception message with stack trace.
        /// </summary>
        /// <param name="ex">The Exception to interrogate.</param>
        /// <returns>Formatted message with stack trace.</returns>
        public static string GetFormattedMessage(this Exception ex)
        {
            return string.Format(@"Exception Message:{0}{1}{0}{0}Stack Trace:{0}{2}",
                Environment.NewLine, ex.Message, ex.StackTrace);
        }
        /// <summary>
        /// Writes an exception message to event log.
        /// </summary>
        /// <param name="ex">The exception to persist.</param>
        /// <param name="eventLogMetadata">Provides source, event id and entry type.</param>
        public static void WriteToEventLog(this Exception ex, EventLogMetadata eventLogMetadata)
        {
            eventLogMetadata.WriteEntry(ex.GetBaseException().GetFormattedMessage());
        }
        /// <summary>
        /// Writes an exception message to event log and suppresses subsequent exceptions, if any arise.
        /// </summary>
        /// <param name="ex">The exception to persist.</param>
        /// <param name="eventLogMetadata">Provides source, event id and entry type.</param>
        public static void WriteToEventLogWithExceptionSuppression(this Exception ex, EventLogMetadata eventLogMetadata)
        {
            try
            {
                ex.WriteToEventLog(eventLogMetadata);
            }
            catch (Exception)
            {
                // suppress exceptions
            }
        }
    }
}
